<?php

namespace app\reserve\controller;

use think\Cache;
use think\Controller;
use app\reserve\model\Order as OrderModel;
use think\Request;
use think\Db;

/**
 * Class Order
 * @package app\reserve\controller
 * @author zhenHong~
 * 用户保养订单
 */
class Order extends Controller
{

    protected $model = '';

    public function __construct(Request $request = null)
    {
        parent::__construct($request);
        $this->model = new OrderModel();
        Vendor('WxPay.lib.WxPay#Api');
        Vendor('WxPay.WxPay#JsApiPay');
    }

    /**
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenHong~
     * @param b_id 车辆品牌id
     * @param t_id 车辆车系id
     * @param m_id 车辆车型id
     * @param a_id 商户id
     */
    public function getCashProductList(Request $request)
    {
        $post = $request->post();
        $data = OrderModel::getAllByCondition($post);
        return apiResponse(200, '查询成功', $data);
    }

    /**
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenHong~
     * 用户下单
     */
    public function createMyOrder(Request $request)
    {
        $data = $request->post();
        $check = $this->validate($data, 'Order.createMyOrder');
        if ($check !== true) {
            return apiResponse(201, $check, '');
        }
        $orderNo = $this->model->createOrder($data);
        if ($orderNo) {
            return apiResponse(200, '下单成功,正在跳转到填写订单信息页面', $orderNo);
        } else {
            return apiResponse(201, '下单失败', '');
        }
    }

    /**
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenHong~
     * 调起微信支付   正式用这个金钱 intval($order['pay_price']*100)
     */
    public function saveUserOrderInfo(Request $request)
    {
        $post = $request->post();
        $check = $this->validate($post, 'Order.saveUserOrderInfo');
        if ($check !== true) {
            return apiResponse(201, $check, '');
        }

        //  判断是否选择了 上门取车
        if ($request->has('get_car') && $request->post('get_car') == '1') {
            $car = $this->validate($post, 'Getcarorder.addCarOrder');
            if ($car !== true) {
                return apiResponse(201, $car, '');
            }
        }

        $bool = $this->model->getByOrderNumberSaveInfo($post);

        if ($bool) {
            $order = OrderModel::where('ordernumber', $post['ordernumber'])->field('u_id,pay_price')->find();

            $callback = 'http://' . $_SERVER['HTTP_HOST'] . '/reserve/order/checkUserOrder';
            $data = $this->wxPayBase($order['pay_price'], $order['u_id'], $post['ordernumber'], $callback);

            // $data = $this->wxPayBase(1, $order['u_id'], $post['ordernumber'], $callback);

            header('Content-Type:application/json; charset=utf-8');

            return $data;
        } else {
            return apiResponse(201, '订单更新失败', '');
        }
    }


    /**
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenHong~
     * 获取当前用户保养订单
     */
    public function selectUserOrder()
    {
        $where = array_filter([
            'O.status' => input('status') ?: ['neq', 9],
            'O.u_id' => input('u_id')
        ], function ($data) {
            if ($data) {
                return true;
            } else {
                return false;
            }
        });
        $page = input('pagenum') ?: 1;
        $result = $this->model->getByUserIdSelectOrder($where, $page);
        return apiResponse(200, '查询成功', $result);
    }


    /**
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenHong~
     * 支付未付款订单  正式用 intval($order['pay_price']*100)
     * 业务逻辑：
     *      1、若存在order_id,则说明用户下单包含：上门取车订单 与 保养订单
     *      2、若接到 ordernumber 说明只是：预约上门 或 预约保养的订单
     */
    public function getByOrderNumberPay()
    {
        if (Request::instance()->has('order_id')) {
            $orderNo = OrderModel::where('id', input('order_id'))->value('ordernumber');
        } else {
            $orderNo = Request::instance()->post('ordernumber');
        }

        $order = OrderModel::where('ordernumber', $orderNo)->field('pay_price,u_id')->find();

        //  微信回调地址
        $callback = 'http://' . $_SERVER['HTTP_HOST'] . '/reserve/order/checkUserOrder';

        //  调起微信支付
        // $data = $this->wxPayBase(1, $order['u_id'], $orderNo, $callback);
        $data = $this->wxPayBase($order['pay_price'], $order['u_id'], $orderNo, $callback);


        header('Content-Type:application/json; charset=utf-8');

        return $data;
    }

    /**
     * @return mixed
     * @author zhenHong~
     * 用户取消未付款订单（取消上门保养、预约到店、上门取车）
     */
    public function resetOrder(Request $request)
    {
        $data = $request->post();
        $check = $this->validate($data, 'Order.resetOrder');
        if ($check !== true) {
            return apiResponse(201, $check, '');
        }
        $num = $this->model->resetUserOrder($data);
        if ($num) {
            return apiResponse(200, '取消订单成功', '');
        } else {
            return apiResponse(201, '取消订单失败', '');
        }
    }

    /**
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenhong~
     * 查询订单详情
     */
    public function detailsUserOrder()
    {
        $orderNo = Request::instance()->post('ordernumber');

        $result = $this->model->getOrderDetailsByOrderNo($orderNo);

        return apiResponse(200, '查询成功', $result);
    }


    /**
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenHong~
     * 订单列表 平台与商户公用
     */
    public function selectOrderList()
    {
        $where = array_filter([
            'status' => input('status') ?: ['neq',9],
            'ordernumber|phone' => input('keyword') ? ['like', input('keyword') . '%'] : '',
            'type' => input('type') ? input('type') : ['in', '1,2'],
            'ctime' => getSelectTime(input('start'), input('end')),
            'a_id' => input('a_id') ?: ''
        ], function ($data) {
            if ($data) {
                return true;
            } else {
                return false;
            }
        });
        $page = input('pagenum') ?: 1;
        $result = $this->model->selectOrder($where, $page);
        return apiResponse(200, '查询成功', $result);
    }

    /**
     * @param Request $request
     * @return mixed
     * @author zhenhong~
     * 商户更改订单状态
     */
    public function updateUserOrderStatus(Request $request)
    {
        $post = $request->post();
        $num = $this->model->setStatusByOrderId($post['id'], $post['status']);
        if ($num) {
            return apiResponse(200, '更改订单状态成功', '');
        } else {
            return apiResponse(201, '更改失败', '');
        }
    }

    /**
     * @param $price
     * @param $uID
     * @param $orderNo
     * @param $callback
     * @return mixed
     * @author zhenhong~
     * 调起微信支付
     */
    public function wxPayBase($price, $uID, $orderNo, $callback)
    {
        //  判断用户id是否存在
        if (empty($uID)) {
            return apiResponse('201', '参数错误', "");
        }
        //  获取用户的openid
        $openid = Db::name("user")->where(['u_id' => $uID])->value('openid');

        //  调起微信统一下单支付接口
        $input = new \WxPayUnifiedOrder();
        $tools = new \JsApiPay();
        $input->SetOpenid($openid);
        $input->SetBody("橙子智能洗车");
        $input->SetAttach("橙子智能洗车");
        $input->SetGoods_tag("橙子智能洗车");
        $input->SetOut_trade_no($orderNo);
        $input->SetTotal_fee($price);
        $input->SetTime_start(date("YmdHis"));
        $input->SetTime_expire(date("YmdHis", time() + 600));
        $input->SetNotify_url($callback);
        $input->SetTrade_type("JSAPI");
        $order = \WxPayApi::unifiedOrder($input, 6);

        //  根据微信返回的通信标识 return_code 判断是否能唤起了支付
        if ($order['return_code'] == "FAIL") {
            return apiResponse(201, "未知错误，请联系管理员！", "");
        }
        //  根据微信提供的交易标识符 result_code 来判断交易是否成功
        if (isset($order['result_code']) && $order['result_code'] == 'FAIL') {
            return apiResponse(201, $order['err_code_des'] ? $order['err_code_des'] : '订单信息错误', "");
        }
        $jsApiParameters = $tools->GetJsApiParameters($order);
        $jsApiParameters = stripslashes($jsApiParameters);

        //  根据当前订单编号缓存prepay_id
        Cache::set('prepay_id' . $orderNo, $order['prepay_id'], 600);

        return apiResponse(200, "成功", $jsApiParameters);
    }

    /**
     * @param $xml
     * @return mixed
     * xml 转array
     */
    public function xmlToArray($xml)
    {
        //将XML转为array
        $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
        return $array_data;
    }


    /**
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     * @author zhenHong~
     * 微信支付回调url
     * 参数1：自己的订单号
     * 参数2：用户的openID
     * 参数3：微信的订单号
     */
    public function checkUserOrder()
    {
        $xml = $GLOBALS['HTTP_RAW_POST_DATA'];
        $xml_res = $this->xmlToArray($xml);
        if ($xml_res['return_code'] == 'SUCCESS') {
            $res = $this->model->saveOrderStatusAddUserBill($xml_res["out_trade_no"], $xml_res['openid'], $xml_res['transaction_id']);
            if ($res) {
                $xml = <<<xml
                    <xml>
                      <return_code><![CDATA[SUCCESS]]></return_code>
                      <return_msg><![CDATA[OK]]></return_msg>
                    </xml>
xml;
                echo $xml;
            }
        }
    }

    /**
     * @param Request $request
     * @return mixed
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @author zhenhong~
     * 用户退款
     */
    public function handleBackMoney(Request $request)
    {
        $post = $request->post();

        $check = $this->validate($post, 'Order.handleBackMoney');

        if ($check !== true) {
            return apiResponse(201, $check, '');
        }

        $result = $this->model->checkOrderInfoByOrderID($post['order_id']);

        // 正式使用 $result['total_fee'], $result['refund_fee']
        $data = $this->returnMoneyToUser($result['out_trade_no'], $result['out_refund_no'], 1, 1);

        header('Content-Type:application/json; charset=utf-8');

        return $data;

    }


    /**
     * @param $tradeNo
     * @param $refundNo
     * @param $totalFee
     * @param $refundFee
     * @return mixed
     * @author zhenhong~
     * 调起微信退款接口
     * 提交退款申请后，退款有一定延时，用零钱支付的退款20分钟内到账，银行卡支付的退款3个工作日后重新查询退款状态。
     */
    public function returnMoneyToUser($tradeNo, $refundNo, $totalFee, $refundFee)
    {
        //  微信退款类
        $refund = new \WxPayRefund();
        $refund->SetOut_trade_no($tradeNo);
        $refund->SetOut_refund_no($refundNo);
        $refund->SetTotal_fee($totalFee);
        $refund->SetRefund_fee($refundFee);
        $refund->SetOp_user_id(\WxPayConfig::MCHID);
        $back = \WxPayApi::refund($refund, 6);

        //  返回结果
        if($back['return_code'] == 'FAIL' ){
            return apiResponse(201,'未知错误,请联系管理员','');
        }

        //  return_code SUCCESS时返回
        if(isset($back['result_code']) && $back['result_code'] == 'FAIL'){
            return apiResponse(201,'提交微信退款失败','');
        }

        return apiResponse(200,'申请成功,钱将在3个工作日内返到您的账户',$back);
    }


    /**
     * @return mixed
     * @throws \think\exception\PDOException
     * @author zhenhong~
     * 查询退款接口
     */
    public function queryOrderBackStatus(){
        $post = Request::instance()->post();
        $orderQuery = new \WxPayRefundQuery();
        $orderQuery->SetOut_trade_no($post['out_trade_no']);
        $orderQuery->SetOut_refund_no($post['out_refund_no']);
        $orderQuery->SetRefund_id($post['refund_id']);
        $orderQuery->SetTransaction_id($post['transaction_id']);
        $query = \WxPayApi::refundQuery($orderQuery, 6);

        if($query['return_code'] == 'FAIL'){
            return apiResponse(201,'退款查询错误','');
        }

        if(isset($query['result_code']) && $query['result_code'] == 'FAIL'){
            return apiResponse(201,'查询失败','');
        }

        if($query['result_code'] == 'SUCCESS' && $query['return_code'] == 'SUCCESS'){
            $result = $this->model->checkBackOrderInfo($post['out_trade_no'],$post['out_refund_no']);
            if($result){
                return apiResponse(200,'退款成功','');
            }else{
                return apiResponse(201,'查询失败','');
            }
        }else{
            return apiResponse(201,'查询失败','');
        }
    }
}